home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
HPAVC
/
HPAVC CD-ROM.iso
/
SICE250.ZIP
/
IOSIM.ASM
< prev
next >
Wrap
Assembly Source File
|
1989-09-04
|
4KB
|
180 lines
PAGE 55,132
TITLE I/O SIMULATION TEST PROGRAM
.286
;
; This is a sample user qualified breakpoint.
;
INT_NUM EQU 65H ;THIS IS THE PSUDEO INTERRUPT NUMBER
REG_WORD STRUC
REG_DI DW ?
REG_SI DW ?
REG_BP DW ?
REG_SP DW ?
REG_BX DW ?
REG_DX DW ?
REG_CX DW ?
REG_AX DW ?
REG_IP DW ?
REG_CS DW ?
REG_FLAGS DW ?
REG_WORD ENDS
REG_BYTE STRUC
REG_DI1 DW ?
REG_SI1 DW ?
REG_BP1 DW ?
REG_SP1 DW ?
REG_BL DB ?
REG_BH DB ?
REG_DL DB ?
REG_DH DB ?
REG_CL DB ?
REG_CH DB ?
REG_AL DB ?
REG_AH DB ?
REG_BYTE ENDS
STACK SEGMENT STACK
DW 50 DUP(0)
STACK ENDS
DATA SEGMENT BYTE PUBLIC 'DATA'
NEW_VAL DW ?
NEXT_IN_LOC DW 0
NEXT_OUT_LOC DW 0
PUBLIC BUFFIN
BUFFIN DW 1000H DUP(0)
PUBLIC BUFFOUT
BUFFOUT DW 1000H DUP(0)
DATA ENDS
CODE SEGMENT PUBLIC 'CODE'
CODE ENDS
LAST SEGMENT PUBLIC 'LAST'
LAST ENDS
CODE SEGMENT BYTE PUBLIC 'CODE'
ASSUME CS:CODE,DS:DATA
PUBLIC START
START: MOV BX,LAST ;THE END OF THE PROGRAM
MOV AX,ES ;SUBTRACT FROM THE TOP OF THE HEADER
SUB BX,AX ;BX NOW HAS THE SIZE TO KEEP WHEN WE
; TERMINATE AND STAY RESIDENT
MOV AX,DATA ;GET OUR DATA SEGMENT
MOV DS,AX
XOR AX,AX ;POINT ES AT SEGMENT ZERO
MOV ES,AX ;
MOV AX,OFFSET IO_ROUTINE ;GET A POINTER TO THE I/O ROUTINE
MOV ES:[INT_NUM*4],AX ;POINT THE INTERRUPT TO THE IO ROUTINE
MOV AX,CS ;GET THE CURRENT SEGMENT
MOV ES:[INT_NUM*4+2],AX ;MOVE IT IN
MOV AH,31H ;USE THE MSDOS KEEP PROCESS FUNCTION
MOV DX,BX ;GET THE SIZE OF OUR ROUTINES
INT 21H ;THATS IT
;---------------------------------------------------------------------------
; This routine will be called when ever Soft-ICE reaches a break point
; and the ACTION is set to our INT_NUM. The stack will be set up as if
; a normal REAL mode interrupt had happend. ie;
;
; FLAGS
; CS
; IP
; The opcodes that we will be looking for are:
; 0ECH - IN AL,DX
; 0EDH - IN AX,DX
; 0EEH - OUT AL,DX
; 0EFH - OUT AX,DX
; Note that bit 02h tells us whether it is an IN or an OUT and bit 01h tells
; us whether it is a BYTE or a WORD.
;
;---------------------------------------------------------------------------
IO_ROUTINE PROC FAR
PUSHA ;SAVE ALL THE CURRENT REGISTERS
MOV BP,SP ;USE BP TO POINT BACK ONTO THE STACK
PUSH DS ;SAVE THE SEGMENTS ALSO
PUSH ES ;
MOV AX,DATA ;GET OUR DATA SEGMENT
MOV DS,AX ;SET IT UP
MOV AX,[BP].REG_CS ;GET THE OLD CS REGISTER
MOV ES,AX ;SET ES TO THAT SEGMENT
MOV SI,[BP].REG_IP ;USE SI TO POINT TO THE IP
MOV AL,ES:[SI-1] ;GET THE OPCODE OF THE I/O INSTRUCTION
CMP AL,0ECH ;WAS IT IN IT I/O OPCODE RANGE?
JB NOT_AN_IO ;NOPE
CMP AL,0EFH ;CHECK THE HIGH END
JA NOT_AN_IO ;NOPE NOT THIS ONE EITHER
MOV DX,[BP].REG_DX ;GET THE DX REGISTER FROM THE STACK
MOV CL,0 ;ASSUME IT WAS A BYTE ACCESS
TEST AL,01H ;WAS IT A BYTE OR A WORD?
JZ BYTE_ACCESS ;YES, JUST A BYTE
MOV CL,1 ;MARK IT AS WORD ACCESS
BYTE_ACCESS:
TEST AL,02H ;WAS IT AN IN OR AN OUT
JNZ OUT_OPCODE ;IT WAS AN OUT
IN_OPCODE:
;---------------------------------------------------------------------------
; ENTRY: CL = BYTE OR WORD ACCESS
; 0 = BYTE
; 1 = WORD
;
; DX = THE I/O PORT
;
; EXIT:
; [BP].REG_AX OR [BP].REG_AL SHOULD HAVE THE SIMULATED VALUE
;
;---------------------------------------------------------------------------
MOV BX,NEXT_IN_LOC
MOV AX,BUFFIN[BX+2]
MOV [BP].REG_AL,AL ;MOVE IN JUST A BYTE
ADD NEXT_IN_LOC,4
MOV AX,NEW_VAL ;GET THE LAST OUTPUT VALUE
OR CL,CL ;IS IT A BYTE OR A WORD
JZ DO_BYTE ;JUST A BYTE
MOV [BP].REG_AX,AX ;MOVE IT IN
JMP IO_DONE
DO_BYTE:
MOV [BP].REG_AL,AL ;MOVE IN JUST A BYTE
JMP IO_DONE
OUT_OPCODE:
;---------------------------------------------------------------------------
; ENTRY: CL = BYTE OR WORD ACCESS
; 0 = BYTE
; 1 = WORD
;
; DX = THE I/O PORT
;
; [BP].REG_AX OR [BP].REG_AL THE VALUE GOING OUT
;
;---------------------------------------------------------------------------
MOV AX,[BP].REG_AX ;GET THE VALUE
MOV NEW_VAL,AX ;SAVE IT
MOV BX,NEXT_OUT_LOC
MOV BUFFOUT[BX],DX
MOV BUFFOUT[BX+2],AX
ADD NEXT_OUT_LOC,4
IO_DONE:
NOT_AN_IO:
POP ES ;RESTORE ALL OF THE SEGMENTS AND REGS
POP DS ;
POPA ;
IRET ;RETURN TO THE INSTRUCTION AFTER THE
; I/O
IO_ROUTINE ENDP
CODE ENDS
END START